package com.ktwlsoft.archivemanage.domain.business.repositoryService;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ktwlsoft.archivemanage.domain.dao.entity.Account;
import com.ktwlsoft.archivemanage.domain.dao.entity.EditHistory;
import com.ktwlsoft.archivemanage.domain.dao.entity.OperationLog;
import com.ktwlsoft.archivemanage.domain.dao.repository.EditHistoryMapper;
import com.ktwlsoft.archivemanage.domain.dao.repository.OperationLogMapper;
import com.ktwlsoft.archivemanage.payload.Result;
import com.ktwlsoft.archivemanage.payload.ResultType;
import com.ktwlsoft.archivemanage.payload.operation.PageRequest;
import com.ktwlsoft.archivemanage.payload.operationLog.SaveEditHistoryRequest;
import com.ktwlsoft.archivemanage.payload.operationLog.SaveLogRequest;
import com.ktwlsoft.archivemanage.service.security.UserPrincipal;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.ktwlsoft.archivemanage.payload.operationLog.FindByPageResult;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;

@Service
public class OperationRepositoryService {

    private final static Logger logger = LoggerFactory.getLogger(OperationRepositoryService.class);

    @Setter
    private static OperationLogMapper operationLogMapper = null;

    @Setter
    private static EditHistoryMapper editHistoryMapper = null;

    public OperationRepositoryService(EditHistoryMapper editHistoryMapper, OperationLogMapper operationLogMapper) {
        OperationRepositoryService.editHistoryMapper = editHistoryMapper;
        OperationRepositoryService.operationLogMapper = operationLogMapper;
    }

    /**
     * 保存日志
     *
     * @param request 日志参数请求
     * @return 日志id
     */
    public static Long saveLog(SaveLogRequest request) {
        Account account = UserPrincipal.getCurrentUser();
        if (account == null) {
            logger.warn("没有获取到当前用户");
        }
        OperationLog operationLog = new OperationLog(
                request.getOperationType(),
                request.getRoute(),
                account != null ? account.getRealName() : "",
                account != null ? account.getId() : 0,
                getIp(),
                new Date(),
                request.getBusinessType(),
                request.getDescription()
        );
        int result = operationLogMapper.insert(operationLog);
        return result > 0 ? operationLog.getId() : null;
    }

    /**
     * 保存日志
     *
     * @param request 日志参数请求
     * @return 日志id
     */
    public static Long saveLog(SaveLogRequest request,Account account) {
        OperationLog operationLog = new OperationLog(
                request.getOperationType(),
                request.getRoute(),
                account != null ? account.getRealName() : "",
                account != null ? account.getId() : 0,
                getIp(),
                new Date(),
                request.getBusinessType(),
                request.getDescription()
        );
        int result = operationLogMapper.insert(operationLog);
        return result > 0 ? operationLog.getId() : null;
    }

    /**
     * 保存操作日志
     *
     * @param result  返回结果
     * @param request 请求
     * @return 日志的id
     */
    public static Long saveLog(Result result, SaveLogRequest request) {
        if (result.getResultType() == ResultType.BUSINESS_SUCCESS) {
            return saveLog(request);
        } else {
            return null;
        }
    }

    /**
     * 保存操作日志和编辑日志
     *
     * @param result             请求结果
     * @param logRequest         日志请求参数
     * @param editHistoryRequest 编辑历史参数
     * @return 日志id
     */
    public static Long saveLog(Result result, SaveLogRequest logRequest, SaveEditHistoryRequest editHistoryRequest) {
        if (result.getResultType() == ResultType.BUSINESS_SUCCESS) {
            Long logId = saveLog(logRequest);
            if (logId != null) {
                editHistoryMapper.insert(new EditHistory(
                        editHistoryRequest.getBusinessFrom(),
                        editHistoryRequest.getBusinessId(),
                        editHistoryRequest.getOldEntity(),
                        editHistoryRequest.getNewEntity(),
                        new Date(),
                        logId
                ));
                return logId;
            }
            return null;
        }
        return null;
    }

    /**
     * 保存编辑历史
     *
     * @param oldEntity    数据库旧值
     * @param newEntity    修改后的值
     * @param businessFrom 业务类型，是个枚举
     * @param businessId   业务主键
     * @param opId         关联的操作历史主键
     */
    public static int saveEditHistory(@NotNull String oldEntity,
                                      @NotNull String newEntity,
                                      @NotNull EditHistory.BusinessFrom businessFrom,
                                      @NotNull Long businessId,
                                      @NotNull Long opId) {
        return editHistoryMapper.insert(new EditHistory(
                businessFrom,
                businessId,
                oldEntity,
                newEntity,
                new Date(),
                opId
        ));
    }

    private static String getIp() {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String remoteAddr = "";
            if (request != null) {
                remoteAddr = request.getHeader("X-FORWARDED-FOR");
                if (remoteAddr == null || "".equals(remoteAddr)) {
                    remoteAddr = request.getRemoteAddr();
                }
            }
            return remoteAddr;
        } catch (Exception ex) {
            logger.error("获取当前IP地址时为获取到ServletRequestAttributes， 消息："+ex.getMessage());
            return "未知IP";
        }
    }

    public PageInfo<FindByPageResult> findByPage(PageRequest request) {
        request.setField(request.getField() != null?request.getField().replaceAll("[A-Z]", "_$0").toLowerCase():null);
        request.setOrder(request.getOrder() != null?request.getOrder().equals("ascend")?"ASC":"DESC":null);
        PageHelper.startPage(request.getPn(), request.getPageSize());
        return new PageInfo<>(operationLogMapper.findByPage(request));
    }

    public List<JSONObject> findList(String operateFrom,String operateTo) {
        PageRequest request = new PageRequest();
        request.setOperationType(OperationLog.OperationType.LOGGING);
        request.setBusinessType(OperationLog.BusinessType.LOGGING);
        request.setOperateFrom(DateUtil.parse(operateFrom));
        request.setOperateTo(DateUtil.parse(operateTo));
        return operationLogMapper.findList(request);
    }

    public EditHistory findDetailByOpId(Long opId) {
        return editHistoryMapper.selectByOpId(opId);
    }
}
